package com.uduemc.biso.node.web.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FileUtils;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.ResponseBody;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.uduemc.biso.core.utils.BisoOrNaplesDomainUtil;
import com.uduemc.biso.node.core.common.entities.SRHtml;
import com.uduemc.biso.node.core.common.utils.SRHtmlUtil;
import com.uduemc.biso.node.core.entities.HRedirectUrl;
import com.uduemc.biso.node.core.property.GlobalProperties;
import com.uduemc.biso.node.core.utils.SitePathUtil;
import com.uduemc.biso.node.web.component.RequestHolder;
import com.uduemc.biso.node.web.component.SiteHolder;
import com.uduemc.biso.node.web.component.SpringContextUtils;
import com.uduemc.biso.node.web.entities.AccessPage;
import com.uduemc.biso.node.web.exception.NotFound404Exception;
import com.uduemc.biso.node.web.service.SRHtmlService;
import com.uduemc.biso.node.web.service.SitemapService;
import com.uduemc.biso.node.web.service.byfeign.RedirectUrlService;
import com.uduemc.biso.node.web.service.byfeign.RobotsService;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;

@Controller
public class SiteController {

    @Resource
    private SRHtmlService sRHtmlServiceImpl;

    @Resource
    private RobotsService robotsServiceImpl;

    @Resource
    private SitemapService sitemapServiceImpl;

    @Resource
    private SiteHolder siteHolder;

    @Resource
    private GlobalProperties globalProperties;

    @Resource
    private RequestHolder requestHolder;

    /**
     * 证书签发验证文件
     *
     * @param md5
     * @throws NotFound404Exception
     */
    @GetMapping({"/index.php/{md5}.html"})
    @ResponseBody
    public void indexPhpMd5Validation(@PathVariable("md5") String md5, HttpServletRequest request, HttpServletResponse response) throws NotFound404Exception {
        String serverName = request.getServerName();
        String serverNameMd5 = SecureUtil.md5(serverName);
        if (!serverNameMd5.equals(md5)) {
            throw new NotFound404Exception("md5 不匹配，md5：" + md5 + ", serverName：" + serverName + ", serverNameMd5：" + serverNameMd5);
        }
        try (OutputStream out = response.getOutputStream();) {
            out.write(md5.getBytes());
            out.flush();
            out.close();
        } catch (IOException e) {
        }
    }

    /**
     * 证书签发验证文件
     *
     * @param pkifilepath
     * @throws NotFound404Exception
     */
    @GetMapping({"/.well-known/pki-validation/{pkifilepath}"})
    @ResponseBody
    public void pkiValidation(@PathVariable("pkifilepath") String pkifilepath, HttpServletRequest request, HttpServletResponse response)
            throws NotFound404Exception {

        String serverName = request.getServerName();
        String trusContent = BisoOrNaplesDomainUtil.getTrusContent(globalProperties.getCenter().getCenterApiDomain(), serverName, pkifilepath);

        if (StrUtil.isBlank(trusContent)) {
            throw new NotFound404Exception("未能获取到锐安信证书的校验内容！");
        }

        response.setContentType("text/plain");
        try (OutputStream out = response.getOutputStream();) {
            out.write(trusContent.getBytes());
            out.flush();
            out.close();
        } catch (IOException e) {
        }
    }

    /**
     * /favicon.ico 网站 ico 图标
     *
     * @return
     * @throws NotFound404Exception
     */
    @GetMapping({"/favicon.ico", "/favicon", "/site/*/favicon.ico", "/site/*/favicon"})
    @ResponseBody
    public void favicon(HttpServletResponse response) throws NotFound404Exception {

        // 获取 ico 文件路径
        String imagePath = SitePathUtil.getUserFaviconIcoPathByCode(globalProperties.getSite().getBasePath(), requestHolder.getHost().getRandomCode());

        if (!(new File(imagePath).isFile())) {
            throw new NotFound404Exception("不存在 favicon.ico 图标");
        }

        File file = new File(imagePath);
        try (FileInputStream openInputStream = FileUtils.openInputStream(file); OutputStream out = response.getOutputStream();) {
            file = new File(imagePath);

            if (openInputStream == null) {
                throw new NotFound404Exception("读取 ico 图片文件失败！ imagePath: " + imagePath);
            }

            long size = file.length();
            response.setHeader("Accept-Ranges", "bytes");
            response.setHeader("Content-Length", "" + size);
            byte[] temp = new byte[(int) size];
            openInputStream.read(temp, 0, (int) size);
            openInputStream.close();
            byte[] data = temp;

            response.setContentType("image/x-icon");
            out.write(data);

            out.flush();
            out.close();
            openInputStream.close();
        } catch (IOException e) {
        }

    }

    /**
     * /robots.txt 网站 robots.txt 内容
     *
     * @return
     * @throws NotFound404Exception
     * @throws IOException
     * @throws JsonProcessingException
     * @throws JsonMappingException
     * @throws JsonParseException
     */
    @GetMapping({"/robots.txt", "/site/*/robots.txt", "/Robots.txt", "/site/*/Robots.txt"})
    @ResponseBody
    public String robots() throws NotFound404Exception, JsonParseException, JsonMappingException, JsonProcessingException, IOException {
        return robotsServiceImpl.robots();
    }

    /**
     * /sitemap.xml 网站 sitemap.xml 内容
     *
     * @return
     * @throws NotFound404Exception
     * @throws IOException
     * @throws JsonProcessingException
     * @throws JsonMappingException
     * @throws JsonParseException
     */
    @GetMapping(value = {"/sitemap.xml", "/site/*/sitemap.xml"}, produces = MediaType.APPLICATION_XML_VALUE)
    @ResponseBody
    public String sitemap(HttpServletResponse response)
            throws NotFound404Exception, JsonParseException, JsonMappingException, JsonProcessingException, IOException {
        response.setContentType("text/xml;charset=UTF-8");
        response.setHeader("Cache-Control", "max-age=3600");
        return sitemapServiceImpl.xml();
    }

    @GetMapping({"/sitemap.html", "/site/*/sitemap.html"})
    @ResponseBody
    public String sitemaphtml(HttpServletResponse response)
            throws NotFound404Exception, JsonParseException, JsonMappingException, JsonProcessingException, IOException {
        response.setContentType("text/html; charset=UTF-8");
        response.setHeader("Cache-Control", "max-age=3600");
        return sitemapServiceImpl.html();
    }

    /**
     * 这里是请求网站的访问路径，拼接HTML后台输出内容
     *
     * @throws IOException
     * @throws JsonProcessingException
     * @throws JsonMappingException
     * @throws JsonParseException
     * @throws NotFound404Exception
     */
    @GetMapping("/**")
    @ResponseBody
    public String index(HttpServletRequest request,HttpServletResponse response)
            throws JsonParseException, JsonMappingException, JsonProcessingException, IOException, NotFound404Exception {

        // 获取 SRHtml 定义对象
        SRHtml srHtml = siteHolder.getSRHtml();

        if (srHtml == null) {
        	RedirectUrlService redirectUrlServiceImpl = SpringContextUtils.getBean("redirectUrlServiceImpl", RedirectUrlService.class);
        	Long hostId = requestHolder.getHost().getId();
    		HRedirectUrl hRedirectUrl = null;
    		try {
    			hRedirectUrl = redirectUrlServiceImpl.findOkOne404ByHostId(hostId);
    		} catch (IOException e) {
    		}
    		if (hRedirectUrl != null) {
    			try {
    				response.sendRedirect(hRedirectUrl.getToUrl());
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    			return "";
    		} else {
    			throw new NotFound404Exception("未能找到对应的 srHtml 数据！ requestURI:" + request.getRequestURI());
    		}
        }

        // 判断是否其他固有页面
        if (otherInherentPages(srHtml)) {
            // 输出对象
            return SRHtmlUtil.getHtml(srHtml);
        }

        // 制作内容
        sRHtmlServiceImpl.makeSRHtml(srHtml);
        // 输出对象
        return SRHtmlUtil.getHtml(srHtml);
    }

    // 其他固有页面
    private boolean otherInherentPages(SRHtml srHtml) throws NotFound404Exception {
        // 判断是否是其他固有页面
        AccessPage accessPage = requestHolder.getAccessPage();
        if (accessPage.getSitePage().boolSearch()) {
            search(srHtml);
            return true;
        }
        return false;
    }

    private void search(SRHtml srHtml) throws NotFound404Exception {
        try {
            sRHtmlServiceImpl.makeSRSearchHtml(srHtml);
        } catch (IOException e) {
        }
    }
    
//    public static void main(String[] arges) throws Exception {
//    	String str = "32674f4d6c793054794735347970544e344a634a756435526d39383539365833343059524e344950765a6a6a49644147746842754675684c674e513242444b425963303854616c466c5258504766476975706c6c5757593841345a7a75354d58795a5a7a6b304c4b674e2f692f5231547638746e6f564561474e4b54394c32475458367353306b38655a592f39664555337a396d756f7a4767534c2b6d5950542b676c38656b39376c555a672f57515a447a7a4c4f697173583838464e43466d4c55612b746b53446f363634312b6e75514669554d75693668584359396e56447245644348634a414e6f64332f69717169616178632f36676f6e6c437a4b327a41443953624946553879734939507745306250323746367879396b6438307668767a776b453834652f74383d";
//    	System.out.println(CryptoJava.de(str));
//    }

}
